package com.bm.beautifulmouse.effect;

import com.bm.beautifulmouse.model.EffectConfig;
import javafx.animation.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.util.Duration;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

public class StarEffect implements Effect {
    private final Random random = new Random();
    private final Queue<Polygon> stars = new LinkedList<>();
    private final Queue<Timeline> animations = new LinkedList<>();
    private static final int MAX_STARS = 30;
    private Polygon lastStar = null;

    // 添加间隔控制
    private long lastGenerateTime = 0;
    private static final long GENERATE_INTERVAL = 50; // 生成间隔(毫秒)
    private double lastX = 0;
    private double lastY = 0;
    private static final double MIN_DISTANCE = 10; // 最小距离阈值

    @Override
    public void generate(Pane container, double x, double y, EffectConfig config) {
        long currentTime = System.currentTimeMillis();
        double distance = Math.sqrt(Math.pow(x - lastX, 2) + Math.pow(y - lastY, 2));

        // 检查时间间隔和距离阈值
        if (currentTime - lastGenerateTime < GENERATE_INTERVAL ||
                (distance < MIN_DISTANCE && !stars.isEmpty())) {
            return;
        }

        // 更新上次生成时间和位置
        lastGenerateTime = currentTime;
        lastX = x;
        lastY = y;

        // 创建新的星星
        Polygon star = createStar(x, y, config);
        container.getChildren().add(star);
        stars.offer(star);
        lastStar = star;

        // 创建星星动画
        Timeline timeline = createAnimation(container, star, config);
        animations.offer(timeline);
        timeline.play();

        // 添加旋转效果
        addRotation(star);

        // 清理旧的星星
        cleanOldStars(container);
    }

    private Polygon createStar(double x, double y, EffectConfig config) {
        double size = 10 * config.getSize();
        Polygon star = new Polygon();

        // 添加随机偏移
        double offsetX = random.nextDouble() * 4 - 2;
        double offsetY = random.nextDouble() * 4 - 2;

        // 创建五角星的点，添加微小随机偏移使每个星星略有不同
        for (int i = 0; i < 5; i++) {
            double angle = 2 * Math.PI * i / 5 - Math.PI / 2;
            double randomOffset = 1 + (random.nextDouble() * 0.2 - 0.1); // ±10%随机变化

            star.getPoints().add(x + offsetX + size * randomOffset * Math.cos(angle));
            star.getPoints().add(y + offsetY + size * randomOffset * Math.sin(angle));

            // 内部点
            angle += Math.PI / 5;
            star.getPoints().add(x + offsetX + size * 0.4 * randomOffset * Math.cos(angle));
            star.getPoints().add(y + offsetY + size * 0.4 * randomOffset * Math.sin(angle));
        }

        // 设置星星颜色和效果
        Color baseColor = config.getColor();
        // 添加随机色相变化
        Color starColor = baseColor.deriveColor(
                random.nextDouble() * 20 - 10, // ±10度色相变化
                1.0,
                0.9 + random.nextDouble() * 0.2, // 随机亮度
                1.0
        );

        star.setFill(starColor);
        star.setStroke(starColor.brighter());
        star.setStrokeWidth(1);

        // 添加发光效果
        javafx.scene.effect.Glow glow = new javafx.scene.effect.Glow(0.8);
        star.setEffect(glow);

        return star;
    }

    private Timeline createAnimation(Pane container, Polygon star, EffectConfig config) {
        // 创建缩放和透明度动画
        ScaleTransition scaleTransition = new ScaleTransition(
                Duration.seconds(0.5 / config.getSpeed()), star);
        scaleTransition.setFromX(0.2);
        scaleTransition.setFromY(0.2);
        scaleTransition.setToX(1.0);
        scaleTransition.setToY(1.0);

        // 添加弹性效果
        scaleTransition.setInterpolator(Interpolator.SPLINE(0.4, 0, 0.2, 1));

        FadeTransition fadeTransition = new FadeTransition(
                Duration.seconds(0.5 / config.getSpeed()), star);
        fadeTransition.setFromValue(1.0);
        fadeTransition.setToValue(0.0);

        // 组合动画
        ParallelTransition parallelTransition = new ParallelTransition(
                star, scaleTransition, fadeTransition);

        parallelTransition.setOnFinished(e -> {
            container.getChildren().remove(star);
            stars.remove(star);
            animations.remove(parallelTransition);
            if (lastStar == star) {
                lastStar = null;
            }
        });

        return new Timeline(
                new KeyFrame(Duration.ZERO,
                        new KeyValue(star.opacityProperty(), 1.0)),
                new KeyFrame(Duration.seconds(0.5 / config.getSpeed()),
                        new KeyValue(star.opacityProperty(), 0.0))
        );
    }

    private void addRotation(Polygon star) {
        RotateTransition rotate = new RotateTransition(Duration.seconds(1), star);
        rotate.setByAngle(360);
        rotate.setCycleCount(Timeline.INDEFINITE);
        // 添加随机初始角度
        star.setRotate(random.nextDouble() * 360);
        rotate.play();
    }

    private void cleanOldStars(Pane container) {
        while (stars.size() >= MAX_STARS) {
            Polygon oldStar = stars.poll();
            Timeline oldAnimation = animations.poll();
            if (oldAnimation != null) {
                oldAnimation.stop();
            }
            container.getChildren().remove(oldStar);
            if (lastStar == oldStar) {
                lastStar = null;
            }
        }
    }
}